package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.domain.StrategyTheme;
import cn.wolfcode.wolf2w.query.StrategyQuery;
import cn.wolfcode.wolf2w.redis.service.IStrategyStatisVORedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.redis.vo.StrategyStatisVO;
import cn.wolfcode.wolf2w.repository.StrategyRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IStrategyCatalogService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.service.IStrategyThemeService;
import cn.wolfcode.wolf2w.util.DateUtil;
import cn.wolfcode.wolf2w.vo.CatalogVo;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 攻略明细业务层的实现类
 */
@Service
public class StrategyServiceImpl implements IStrategyService {

    //  注入StrategyRepository持久层接口
    @Autowired
    private StrategyRepository strategyRepository;

    //  注入IStrategyThemeService业务层接口
    @Autowired
    private IStrategyThemeService strategyThemeService;

    //  注入IStrategyCatalogService业务层接口
    @Autowired
    private IStrategyCatalogService strategyCatalogService;

    @Autowired
    private IDestinationService destinationService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //  注入MongoTemplate服务
    @Autowired
    private MongoTemplate mongoTemplate;

    //  插入单个方法
    @Override
    public void insert(Strategy strategy) {

        //  id自动生成，手动设置为空
        strategy.setId(null);

        //  调用持久层接口的save方法执行插入单个攻略明细对象
        strategyRepository.save(strategy);
    }

    //  删除单个方法
    @Override
    public void deleteById(String id) {

        //  调用持久层接口的deleteById方法执行删除单个攻略明细对象
        strategyRepository.deleteById(id);
    }

    //  修改单个方法
    @Override
    public void updateById(Strategy strategy) {

        //  调用持久层接口的save方法执行修改单个攻略明细对象
        strategyRepository.save(strategy);
    }

    //  查询单个方法
    @Override
    public Strategy selectById(String id) {

        //  调用持久层接口的findById方法执行查询单个攻略明细对象
        return strategyRepository.findById(id).orElse(null);
    }

    //  查询所有方法
    @Override
    public List<Strategy> selectAll() {

        //  调用持久层接口的findAll方法执行查询所有攻略明细对象
        return strategyRepository.findAll();
    }

    //  分页方法
    @Override
    public Page<Strategy> query(StrategyQuery qo) {

        //  查询对象
        Query query = new Query();

        if (StringUtils.hasLength(qo.getDestId())) {
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }

        if (StringUtils.hasLength(qo.getThemeId())) {
            query.addCriteria(Criteria.where("themeId").is(qo.getThemeId()));
        }

        //  调用mongodb服务中的count方法
        //  传入上面的查询对象和Strategy的字节码对象
        //  返回一个满足条件的总记录数
        long totalCount = mongoTemplate.count(query, Strategy.class);

        //  若查询出来的总记录数为零时
        if (totalCount == 0) {

            //  直接返回一个空集合
            return Page.empty();
        }

        //  调用Pageable的of方法
        //  传入qo对象的当前页，qo对象的当前页显示的最大记录数，排序的顺序，通过_id来排序
        Pageable pageRequest = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");

        //  把限制条件加入到查询对象中
        query.with(pageRequest);

        //  调用mongodb服务中的find方法
        //  传入上面的查询对象和Strategy的字节码对象
        //  返回一个满足条件的攻略明细对象的集合数据
        List<Strategy> strategys = mongoTemplate.find(query, Strategy.class);

        //  返回一个PageImpl的集合
        //  传入一个满足条件的攻略明细对象的集合数据对象
        //  传入限制条件
        //  返回一个满足条件的总记录数
        return new PageImpl<>(strategys, pageRequest, totalCount);
    }

    //  设置热门攻略明细
    /*
        @Override
        public Strategy setChangeState(int state, String id) {

            //  调本类的selectById方法通过id查询攻略明细对象
            Strategy strategy = this.selectById(id);

            //  将传过来的state设置到查询出来的攻略明细
            strategy.setState(state);

            //  调用本类的updateById方法进行修改
            this.updateById(strategy);

            //  返回strategy对象
            return strategy;
        }
    */
    @Override
    public void setChangeState(int state, String id){
        //  查询对象
        Query query = new Query();
        //  编写限制条件
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("state", state);
        mongoTemplate.updateMulti(query, update, Strategy.class);
    }

    //  添加或更新
    @Override
    public void saveOrUpdate(Strategy strategy) throws ParseException {
        //  目的地id
        StrategyCatalog strategyCatalog = strategyCatalogService.selectById(strategy.getCatalogId());
        strategy.setDestId(strategyCatalog.getDestId());

        //  目的地name
        strategy.setDestName(strategyCatalog.getDestName());

        //  主题名称
        StrategyTheme strategyTheme = strategyThemeService.selectById(strategy.getThemeId());
        strategy.setThemeName(strategyTheme.getName());

        //  分类名称
        strategy.setCatalogName(strategyCatalog.getName());

        //  是否国外
        List<Destination> destinations = destinationService.queryByParentId(strategyCatalog.getDestId());
        if (destinations != null && destinations.size() > 0) {
            Destination destination = destinations.get(0);
            if ("中国".equals(destination.getName())) {
                strategy.setIsabroad(Strategy.ABROAD_NO);
            } else {
                strategy.setIsabroad(Strategy.ABROAD_YES);
            }
        }

        if (StringUtils.hasLength(strategy.getId())) {
            //  查询
            Strategy temp = this.selectById(strategy.getId());
            //  更新
            strategy.setCreateTime(temp.getCreateTime());
            strategy.setFavornum(temp.getFavornum());
            strategy.setReplynum(temp.getReplynum());
            strategy.setSharenum(temp.getSharenum());
            strategy.setThumbsupnum(temp.getThumbsupnum());
            //  修改
            this.updateById(strategy);
        } else {
            //  调用日期工具类
            strategy.setCreateTime(DateUtil.getTime());
            this.insert(strategy);
        }

    }

    //  攻略点击量前3
    @Override
    public List<Strategy> queryViewmunTop3(String destId) {

        //  编写排序条件
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC, "viewnum");

        //  按照目的地id查询所有的攻略分类对象
        List<Strategy> strategyList = strategyRepository.findByDestId(destId, pageable);

        //  返回
        return strategyList;
    }

    //  攻略集合
    @Override
    public List<String> queryStrategiesFavor(String sid, String userId) {
        //  拼接key
        String key = RedisKeys.STRATEGT_USER_FAVOR.join(userId);
        //  通过key获取到value
        String value = stringRedisTemplate.opsForValue().get(key);
        //  创建一个sid集合
        List<String> sidList = new ArrayList<>();
        //  将value值转成String类型的集合
        sidList = JSON.parseArray(value, String.class);
        //  判断该集合是否为空，有长度
        if (sidList !=  null &&  sidList.size() > 0){
            //  若当前攻略id不在sid集合中
            //  则说明，没有被收藏
            if (!sidList.contains(sid)) {
                //  返回一个空集合
                sidList = Collections.EMPTY_LIST;
            } else {
                //  添加到sid集合中
                sidList.add(sid);
            }
        }
        //  返回sid集合
        return sidList;
    }

    //  修改攻略里面的数据
    @Override
    public void updateStrategyVo(StrategyStatisVO strategyStatisVO) {
        //  查询对象
        Query query = new Query();
        //  添加限制条件
        query.addCriteria(Criteria.where("_id").is(strategyStatisVO.getStrategyId()));
        //  部分更新
        Update update = new Update();
        //  修改部分数据
        update.set("viewnum", strategyStatisVO.getViewnum());
        update.set("replynum", strategyStatisVO.getReplynum());
        update.set("favornum", strategyStatisVO.getFavornum());
        update.set("sharenum", strategyStatisVO.getSharenum());
        update.set("thumbsupnum", strategyStatisVO.getThumbsupnum());
        //  更新
        mongoTemplate.updateMulti(query, update, Strategy.class);
    }

    @Override
    public List<Strategy> queryDestName(String keyword) {
        return strategyRepository.findByDestName(keyword);
    }


}
